{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "logical and：\n",
      "epoch 0 sample [0 1 2 0 0 0 0]\n",
      "epoch 0 sample [1 1 2 0 1 -1 0]\n",
      "epoch 0 sample [2 0 2 -1 1 0 -1]\n",
      "epoch 0 sample [3 0 1 -2 0 1 1]\n",
      "epoch 1 sample [0 1 2 -1 0 0 0]\n",
      "epoch 1 sample [1 1 2 -1 0 0 0]\n",
      "epoch 1 sample [2 1 2 -1 1 0 -1]\n",
      "epoch 1 sample [3 1 1 -2 0 1 1]\n",
      "epoch 2 sample [0 2 2 -1 0 0 0]\n",
      "epoch 2 sample [1 2 2 -1 1 -1 0]\n",
      "epoch 2 sample [2 1 2 -2 0 0 0]\n",
      "epoch 2 sample [3 1 2 -2 1 0 0]\n",
      "epoch 3 sample [0 1 2 -2 0 0 0]\n",
      "epoch 3 sample [1 1 2 -2 0 0 0]\n",
      "epoch 3 sample [2 1 2 -2 0 0 0]\n",
      "epoch 3 sample [3 1 2 -2 1 0 0]\n",
      "epoch 4 sample [0 1 2 -2 0 0 0]\n",
      "epoch 4 sample [1 1 2 -2 0 0 0]\n",
      "epoch 4 sample [2 1 2 -2 0 0 0]\n",
      "epoch 4 sample [3 1 2 -2 1 0 0]\n",
      "epoch 5 sample [0 1 2 -2 0 0 0]\n",
      "epoch 5 sample [1 1 2 -2 0 0 0]\n",
      "epoch 5 sample [2 1 2 -2 0 0 0]\n",
      "epoch 5 sample [3 1 2 -2 1 0 0]\n",
      "epoch 6 sample [0 1 2 -2 0 0 0]\n",
      "epoch 6 sample [1 1 2 -2 0 0 0]\n",
      "epoch 6 sample [2 1 2 -2 0 0 0]\n",
      "epoch 6 sample [3 1 2 -2 1 0 0]\n",
      "epoch 7 sample [0 1 2 -2 0 0 0]\n",
      "epoch 7 sample [1 1 2 -2 0 0 0]\n",
      "epoch 7 sample [2 1 2 -2 0 0 0]\n",
      "epoch 7 sample [3 1 2 -2 1 0 0]\n",
      "epoch 8 sample [0 1 2 -2 0 0 0]\n",
      "epoch 8 sample [1 1 2 -2 0 0 0]\n",
      "epoch 8 sample [2 1 2 -2 0 0 0]\n",
      "epoch 8 sample [3 1 2 -2 1 0 0]\n",
      "epoch 9 sample [0 1 2 -2 0 0 0]\n",
      "epoch 9 sample [1 1 2 -2 0 0 0]\n",
      "epoch 9 sample [2 1 2 -2 0 0 0]\n",
      "epoch 9 sample [3 1 2 -2 1 0 0]\n",
      "logical or：\n",
      "epoch 0 sample [0 1 2 0 0 0 0]\n",
      "epoch 0 sample [1 1 2 0 1 0 0]\n",
      "epoch 0 sample [2 1 2 0 1 0 0]\n",
      "epoch 0 sample [3 1 2 0 1 0 0]\n",
      "epoch 1 sample [0 1 2 0 0 0 0]\n",
      "epoch 1 sample [1 1 2 0 1 0 0]\n",
      "epoch 1 sample [2 1 2 0 1 0 0]\n",
      "epoch 1 sample [3 1 2 0 1 0 0]\n",
      "epoch 2 sample [0 1 2 0 0 0 0]\n",
      "epoch 2 sample [1 1 2 0 1 0 0]\n",
      "epoch 2 sample [2 1 2 0 1 0 0]\n",
      "epoch 2 sample [3 1 2 0 1 0 0]\n",
      "epoch 3 sample [0 1 2 0 0 0 0]\n",
      "epoch 3 sample [1 1 2 0 1 0 0]\n",
      "epoch 3 sample [2 1 2 0 1 0 0]\n",
      "epoch 3 sample [3 1 2 0 1 0 0]\n",
      "epoch 4 sample [0 1 2 0 0 0 0]\n",
      "epoch 4 sample [1 1 2 0 1 0 0]\n",
      "epoch 4 sample [2 1 2 0 1 0 0]\n",
      "epoch 4 sample [3 1 2 0 1 0 0]\n",
      "epoch 5 sample [0 1 2 0 0 0 0]\n",
      "epoch 5 sample [1 1 2 0 1 0 0]\n",
      "epoch 5 sample [2 1 2 0 1 0 0]\n",
      "epoch 5 sample [3 1 2 0 1 0 0]\n",
      "epoch 6 sample [0 1 2 0 0 0 0]\n",
      "epoch 6 sample [1 1 2 0 1 0 0]\n",
      "epoch 6 sample [2 1 2 0 1 0 0]\n",
      "epoch 6 sample [3 1 2 0 1 0 0]\n",
      "epoch 7 sample [0 1 2 0 0 0 0]\n",
      "epoch 7 sample [1 1 2 0 1 0 0]\n",
      "epoch 7 sample [2 1 2 0 1 0 0]\n",
      "epoch 7 sample [3 1 2 0 1 0 0]\n",
      "epoch 8 sample [0 1 2 0 0 0 0]\n",
      "epoch 8 sample [1 1 2 0 1 0 0]\n",
      "epoch 8 sample [2 1 2 0 1 0 0]\n",
      "epoch 8 sample [3 1 2 0 1 0 0]\n",
      "epoch 9 sample [0 1 2 0 0 0 0]\n",
      "epoch 9 sample [1 1 2 0 1 0 0]\n",
      "epoch 9 sample [2 1 2 0 1 0 0]\n",
      "epoch 9 sample [3 1 2 0 1 0 0]\n",
      "logical xor：\n",
      "epoch 0 sample [0 1 2 0 0 0 0]\n",
      "epoch 0 sample [1 1 2 0 1 0 0]\n",
      "epoch 0 sample [2 1 2 0 1 0 0]\n",
      "epoch 0 sample [3 1 2 0 1 -1 -1]\n",
      "epoch 1 sample [0 0 1 -1 0 0 0]\n",
      "epoch 1 sample [1 0 1 -1 0 1 0]\n",
      "epoch 1 sample [2 1 1 0 1 0 0]\n",
      "epoch 1 sample [3 1 1 0 1 -1 -1]\n",
      "epoch 2 sample [0 0 0 -1 0 0 0]\n",
      "epoch 2 sample [1 0 0 -1 0 1 0]\n",
      "epoch 2 sample [2 1 0 0 0 0 1]\n",
      "epoch 2 sample [3 1 1 1 1 -1 -1]\n",
      "epoch 3 sample [0 0 0 0 0 0 0]\n",
      "epoch 3 sample [1 0 0 0 0 1 0]\n",
      "epoch 3 sample [2 1 0 1 1 0 0]\n",
      "epoch 3 sample [3 1 0 1 1 -1 -1]\n",
      "epoch 4 sample [0 0 -1 0 0 0 0]\n",
      "epoch 4 sample [1 0 -1 0 0 1 0]\n",
      "epoch 4 sample [2 1 -1 1 0 0 1]\n",
      "epoch 4 sample [3 1 0 2 1 -1 -1]\n",
      "epoch 5 sample [0 0 -1 1 1 0 0]\n",
      "epoch 5 sample [1 0 -1 0 0 1 0]\n",
      "epoch 5 sample [2 1 -1 1 0 0 1]\n",
      "epoch 5 sample [3 1 0 2 1 -1 -1]\n",
      "epoch 6 sample [0 0 -1 1 1 0 0]\n",
      "epoch 6 sample [1 0 -1 0 0 1 0]\n",
      "epoch 6 sample [2 1 -1 1 0 0 1]\n",
      "epoch 6 sample [3 1 0 2 1 -1 -1]\n",
      "epoch 7 sample [0 0 -1 1 1 0 0]\n",
      "epoch 7 sample [1 0 -1 0 0 1 0]\n",
      "epoch 7 sample [2 1 -1 1 0 0 1]\n",
      "epoch 7 sample [3 1 0 2 1 -1 -1]\n",
      "epoch 8 sample [0 0 -1 1 1 0 0]\n",
      "epoch 8 sample [1 0 -1 0 0 1 0]\n",
      "epoch 8 sample [2 1 -1 1 0 0 1]\n",
      "epoch 8 sample [3 1 0 2 1 -1 -1]\n",
      "epoch 9 sample [0 0 -1 1 1 0 0]\n",
      "epoch 9 sample [1 0 -1 0 0 1 0]\n",
      "epoch 9 sample [2 1 -1 1 0 0 1]\n",
      "epoch 9 sample [3 1 0 2 1 -1 -1]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "#逻辑与数据\n",
    "samples_and = [\n",
    "    [0, 0, 0],\n",
    "    [1, 0, 0],\n",
    "    [0, 1, 0],\n",
    "    [1, 1, 1],\n",
    "]\n",
    "\n",
    "#逻辑或数据\n",
    "samples_or = [\n",
    "    [0, 0, 0],\n",
    "    [1, 0, 1],\n",
    "    [0, 1, 1],\n",
    "    [1, 1, 1],\n",
    "]\n",
    "\n",
    "#逻辑异或数据\n",
    "samples_xor = [\n",
    "    [0, 0, 0],\n",
    "    [1, 0, 1],\n",
    "    [0, 1, 1],\n",
    "    [1, 1, 0],\n",
    "]\n",
    "\n",
    "def perception(samples):\n",
    "    #权重\n",
    "    w=np.array([1,2])\n",
    "    #偏置\n",
    "    b=0\n",
    "    a=1\n",
    "    #训练10遍\n",
    "    for i in range(10):\n",
    "        for j in range(4):\n",
    "            #矩阵的第j行的前两个数值\n",
    "            x=np.array(samples[j][:2])\n",
    "            #将未激活的值输入sigmoid函数 dot:向量的点乘运算\n",
    "            if np.dot(w,x)+b >0:\n",
    "                y=1\n",
    "            else:\n",
    "                y=0\n",
    "            #真实值\n",
    "            d=np.array(samples[j][2])\n",
    "            delta_b=a*(d-y)\n",
    "            delta_w=a*(d-y)*x\n",
    "            print('epoch {} sample [{} {} {} {} {} {} {}]'.format(\n",
    "                i,j,w[0],w[1],b,y,delta_w[0],delta_w[1],delta_b\n",
    "            ))\n",
    "            #反向传播，更新权重\n",
    "            w=w+delta_w\n",
    "            b=b+delta_b\n",
    "\n",
    "if __name__=='__main__':\n",
    "    print('logical and：')\n",
    "    perception(samples_and)\n",
    "    print('logical or：')\n",
    "    perception(samples_or)\n",
    "    print('logical xor：')\n",
    "    perception(samples_xor)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "从逻辑与的输出中可以看出从第三次训练后，通过神经网络的BP，权重w0,w1和b已经趋于稳定w0=1,w1=2,b=-2\n",
    "\n",
    "对于逻辑或，从输出样本的第一次训练之后，对权重和偏置的BP趋于稳定，w0=1,w1=2,b=0\n",
    "\n",
    "对于异或数据的训练，每一次反馈得到的w0,w1和b都不同，可以得出感知器不能实现异或的功能，也就是不能训练处得到实现异或功能的模型。\n",
    "\n",
    "原因：逻辑与和逻辑或都是线性的模型，它的输入和输出都是在一条直线上，这条直线将平面区域分割为两份，在直线的两端分别满足大于和小于0，在直线上  满足等于0,也就是说它是线性的。而逻辑异或它在平面区域中是两条交叉的直线，也就是说它是线性不可分的，所以无法得到稳定的反馈。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
